<template>
  <div>
    <el-card>
      <el-row>
        <div class="table-header-options">
          <el-button type="primary" :icon="Plus" @click="toAdd()" v-button="['api:sys:sysmenu:create']">
            新增
          </el-button>
          <el-button type="success" :icon="Search">查询</el-button>
        </div>
      </el-row>
      <el-row>
        <el-table ref="treeTable" :data="tableList" row-key="id" :border="true"
          :header-cell-style="{ background: '#eef1f6', color: '#606266' }" lazy :load="load" :table-layout="'auto'"
          :tree-props="{ hasChildren: 'hasChildren' }">
          <el-table-column prop="name" label="菜单名称">
            <template #default="{ row }">
              <svg-icon :icon-class="row.icon" />
              {{ row.name }}
            </template>
          </el-table-column>
          <el-table-column prop="menuType" label="菜单类型">
            <template #default="{ row }">
              <el-tag :type="row.menuType === MenuTypeEnum.Group
                  ? 'success'
                  : row.menuType === MenuTypeEnum.Menu
                    ? 'danger'
                    : row.menuType === MenuTypeEnum.List
                      ? 'warning'
                      : 'primary'
                ">
                {{ menuTypeFilter(row) }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column label="权限地址" :show-overflow-tooltip="true">
            <template #default="{ row }">
              <span v-if="row.menuType === MenuTypeEnum.Group">
                页面路径：{{ row.webFilePath }}
              </span>
              <span v-if="row.menuType === MenuTypeEnum.Menu">
                路由名称：{{ row.routerName }}，页面路径：{{ row.webFilePath }}
              </span>
              <span v-if="row.menuType === MenuTypeEnum.List || row.menuType === MenuTypeEnum.Button">
                权限标识：{{ row.permission }}，接口地址：{{ row.apiUrl }}
              </span>
            </template>
          </el-table-column>
          <el-table-column label="操作">
            <template #default="{ row }">
              <el-button type="primary" :icon="EditPen" @click="toEdit(row)" v-button="['api:sys:sysmenu:update']">
                编辑
              </el-button>
              <el-popconfirm title="确定要删除这条数据?" @confirm="toDelete(row)">
                <template #reference>
                  <el-button type="danger" :icon="Delete" v-button="['api:sys:sysmenu:delete']">
                    删除
                  </el-button>
                </template>
              </el-popconfirm>
            </template>
          </el-table-column>
        </el-table>
      </el-row>
      <el-row>
        <div class="table-buttom-options">
          <Pagination :total="search.total" v-model:pageIndex="search.pageIndex" v-model:pageSize="search.pageSize"
            @change="query()"></Pagination>
        </div>
      </el-row>
    </el-card>

    <Edit v-if="open" v-model="open" :type="editEnum" :info="info" :parentId="parentId" :menuTypeList="menuTypeList"
      @success="query()" @reloadSub="reloadSub"></Edit>
  </div>
</template>

<script lang="ts" setup>
import Edit from "@/views/sys/sysmenu/edit.vue";
import { Plus, Delete, EditPen, Search } from "@element-plus/icons-vue";
import Pagination from "@/components/pagination/pagination.vue";
import successMsg from "@/utils/successMsg";
import { TreeNode } from "element-plus";
import EnumApi, { EnumData } from "@/api/enums";
import { MenuTypeEnum } from "@/enums/MenuTypeEnum";
import MenuApi, { SysMenu } from "@/api/sys/menu";
import { EditEnum } from "@/enums/EditEnum";
defineOptions({
  name: "sysmenu",
  inherititems: false,
});
const treeTable = ref(null);

//查询条件
const search = reactive({
  searchString: "",
  total: 0,
  pageIndex: 1, //第几页
  pageSize: 10, //每页多少条
});

//表格数据
const tableList = ref<SysMenu[]>([]);

const editEnum = ref<number>();
onMounted(async() => {
  await getMenuTypeList();
  await query();
});

const query = async () => {
  const { dataList, totalCount } = await MenuApi.query(search);
  tableList.value = dataList;
  search.total = totalCount;
};

const menuTypeList = ref<EnumData[]>([]);
const getMenuTypeList = async () => {
  menuTypeList.value = await EnumApi.QueryMenuTypeEnums();
};

const menuTypeFilter = computed(() => (item: SysMenu) => {
  return menuTypeList.value.find((x) => x.value === item.menuType)?.text;
});

const maps = new Map();
const load = async (
  row: SysMenu,
  treeNode: TreeNode,
  resolve: (data: SysMenu[], expanded?: boolean) => void
) => {
  // load 函数中的将当前行信息保存
  maps.set(row.id, { row, treeNode, resolve });

  if (row.id) {
    const list = await MenuApi.querySubMenu(row.id);

    const store = treeTable.value.store;
    const lazyTreeNodeMap = store.states.lazyTreeNodeMap;

    //为了刷新折叠按钮，源码里面有最下面一行逻辑
    resolve(list);

    //解决最后一个节点删除和新增节点，无法刷新问题
    lazyTreeNodeMap.value[row.id] = list;
  }
};

const reloadSub = async (rowData: SysMenu, rowParentId: string) => {
  if ((rowParentId == null || rowParentId == "") && !maps.has(rowData.parentId)) {
    query();
  } else {
    if (maps.has(rowParentId)) {
      const { row, treeNode, resolve } = maps.get(rowParentId);
      load(row, treeNode, resolve);
    } else {
      const store = treeTable.value.store;
      const treeNodeMap = store.states.treeData.value;
      const node = treeNodeMap[rowParentId];

      const menu = {
        id: "",
        parentId: null,
        name: "",
        icon: "",
        hasChildren: false,
        menuType: MenuTypeEnum.Group,
        apiUrl: "",
        permission: "",
        routerName: "",
        routerUrl: "",
        webFilePath: "",
        order: null,
        hidden: false,
        children: [],
      };
      menu.id = rowParentId;
      load(menu, node, (data: SysMenu[]) => { });
    }
  }
};

const title = ref("");
const open = ref(false);
const toAdd = () => {
  info.value = {
    id: "",
    parentId: null,
    name: "",
    icon: "",
    hasChildren: false,
    menuType: MenuTypeEnum.Group,
    apiUrl: "",
    permission: "",
    routerName: "",
    routerUrl: "",
    webFilePath: "",
    order: null,
    hidden: false,
    children: [],
  };
  editEnum.value = EditEnum.create;
  title.value = "新增";
  open.value = true;
};

const info = ref<SysMenu>();
const parentId = ref(null);
const toEdit = (row: SysMenu) => {
  info.value = Object.assign({}, row);
  parentId.value = row.parentId;
  editEnum.value = EditEnum.update;
  title.value = "修改";
  open.value = true;
};

const toDelete = async (row: SysMenu) => {
  const { success, message } = await MenuApi.delete(row.id);
  successMsg(success, message, await reloadSub(row, row.parentId));
};
</script>

<style lang="scss" scoped>
:deep(.el-tooltip) {
  width: auto !important;
}
</style>
